package com.mlethe.library.qrcode.zxing;

import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Size;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import com.google.zxing.DecodeHintType;
import com.google.zxing.Result;
import com.mlethe.library.camera.widget.CameraTextureView;

import java.util.Map;

/**
 * @author Mlethe
 */
public class QRCodeView extends FrameLayout implements CameraTextureView.SurfaceViewListener {

    private ScanBoxView mScanBoxView;
    private ScanDelegate mScanDelegate;
    private DecodeThread mDecodeThread;

    private Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            int what = msg.what;
            if (what == 1000) {
                Result result = (Result) msg.obj;
                Log.e("yym", "handleMessage: " + result.getText());
            }
        }
    };

    public QRCodeView(@NonNull Context context) {
        this(context, null);
    }

    public QRCodeView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public QRCodeView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        CameraTextureView textureView = new CameraTextureView(context);
        textureView.setSurfaceViewListener(this);
        addView(textureView);
        mScanBoxView = new ScanBoxView(context, attrs);
        addView(mScanBoxView);
        mDecodeThread = new DecodeThread(mHandler);
        mDecodeThread.start();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public void onPreviewFrame(byte[] data, Size size) {
        if (mDecodeThread != null) {
            Message message = Message.obtain(mDecodeThread.getHandler(), DecodeHandler.DECODE_CODE, size.getWidth(), size.getHeight(), data);
            message.sendToTarget();
        }
    }

    @Override
    public void onCameraBrightnessChanged(boolean isDark) {
        if (mScanDelegate != null) {
            mScanDelegate.onCameraBrightnessChanged(isDark);
        }
    }

    @Override
    public void onOpenCameraError() {
        if (mScanDelegate != null) {
            mScanDelegate.onOpenCameraError();
        }
    }

    /**
     * 设置识别的格式
     *
     * @param barcodeType 识别的格式
     * @param hintMap     barcodeType 为 BarcodeType.CUSTOM 时，必须指定该值
     */
    public QRCodeView setType(BarcodeType barcodeType, Map<DecodeHintType, Object> hintMap) {
        if (mDecodeThread != null) {
            mDecodeThread.setType(barcodeType, hintMap);
        }
        return this;
    }

    public QRCodeView setScanDelegate(ScanDelegate scanDelegate) {
        this.mScanDelegate = scanDelegate;
        return this;
    }

    public interface ScanDelegate {
        /**
         * 处理扫描结果
         *
         * @param result 摄像头扫码时只要回调了该方法 result 就一定有值，不会为 null。解析本地图片或 Bitmap 时 result 可能为 null
         */
        void onSuccess(String result);

        /**
         * 摄像头环境亮度发生变化
         *
         * @param isDark 是否变暗
         */
        void onCameraBrightnessChanged(boolean isDark);

        /**
         * 处理打开相机出错
         */
        void onOpenCameraError();
    }
}
